# coding=utf-8
"""
读取配置文件
"""

import configparser
from configparser import NoOptionError, NoSectionError

import codecs  # 转换编码格式
import traceback
from typing import NoReturn, Dict, List
import os
from Common.public.readfile import Readfile

from logzero import logger

BASE_DIR = os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
CONFIG_PATH = BASE_DIR + r"\config.ini"


class GetConfig(object):
    @staticmethod
    def get_config() -> configparser.ConfigParser:
        config = configparser.ConfigParser()
        with open(
                file=CONFIG_PATH, mode="rb"
        ) as f:  # 2018-6-10 BEGIN 判断文件的编码类型 如果是UTF-8 BOM格式，则将其转化为无BOM格式
            s = f.read()
        if s.startswith(codecs.BOM_UTF8):  # 带BOM的文件是以 b'\xef\xbb\xbf' 开头
            s = s[len(codecs.BOM_UTF8):]  # 截取 b'\xef\xbb\xbf' 到文件结尾
            with open(file=CONFIG_PATH, mode="wb") as f:  # 保存为无BOM格式
                f.write(s)
        coding = Readfile.get_file_coding(filepath=CONFIG_PATH).get("encoding")
        config.read(filenames=CONFIG_PATH, encoding=coding
                    )  # 2018-6-10 END 判断文件的编码类型 如果是UTF-8 BOM格式，则将其转化为无BOM格式
        return config

    def _write_config(self, config):
        """写入配置"""
        coding = Readfile.get_file_coding(filepath=CONFIG_PATH).get("encoding")
        with open(CONFIG_PATH, mode='w', encoding=coding) as f:
            config.write(f)

    def _prop_setter(self, section, option, value):
        """添加配置"""
        try:
            config = self.get_config()
            config.set(section=section, option=option, value=value)
            self._write_config(config)
        except Exception as e:
            err_msg = '...\\项目目录\\Config\\config.ini更新配置 %s.%s 选项 值 "%s" 出错。\n错误详情：\n %s' % \
                      (section, option, value, traceback.format_exc())
            logger.warning(err_msg)
            raise RuntimeError(err_msg) from e  # 供web捕获异常，前台提示

    def _delete_all_options(self, section):
        """删除全部配置"""
        config = self.get_config()
        options = config.options(section=section)
        for option in options:
            config.remove_option(section=section, option=option)
        self._write_config(config=config)

    @property
    def BASE_DIR(self) -> str:
        return BASE_DIR

    @property
    def CONFIG_PATH(self) -> str:
        return CONFIG_PATH

    @property
    def period(self) -> str:
        section = "PROJECT"
        option = "period"
        default = "demo"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @period.setter
    def period(self, value) -> NoReturn:
        section = "PROJECT"
        option = "period"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def manage_case_type(self) -> str:
        """组织管理案例方式"""
        section = "PROJECT"
        option = "manage_case_type"
        default = 'excel'
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @property
    def browser_type(self) -> str:
        section = "Driver"
        option = "browser_type"
        default = "Chrome"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @browser_type.setter
    def browser_type(self, value) -> NoReturn:
        section = "Driver"
        option = "browser_type"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def timeout(self) -> int:
        section = "Driver"
        option = "timeout"
        default = 10
        try:
            value = self.get_config().getint(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @timeout.setter
    def timeout(self, value) -> NoReturn:
        section = "Driver"
        option = "timeout"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def headless(self) -> bool:
        section = "Driver"
        option = "headless"
        default = False
        try:
            value = self.get_config().getboolean(section=section,
                                                 option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @headless.setter
    def headless(self, value) -> NoReturn:
        section = "Driver"
        option = "headless"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def send_email(self) -> bool:
        section = "EMAIL"
        option = "send_email"
        default = False
        try:
            value = self.get_config().getboolean(section=section,
                                                 option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @send_email.setter
    def send_email(self, value) -> NoReturn:
        section = "EMAIL"
        option = "send_email"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def smtp_login_name(self) -> str:
        section = "EMAIL"
        option = "smtp_login_name"
        default = "********@outlook.com"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @smtp_login_name.setter
    def smtp_login_name(self, value) -> NoReturn:
        section = "EMAIL"
        option = "smtp_login_name"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def smtp_login_passwd(self) -> str:
        section = "EMAIL"
        option = "smtp_login_passwd"
        default = "**********"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @smtp_login_passwd.setter
    def smtp_login_passwd(self, value) -> NoReturn:
        section = "EMAIL"
        option = "smtp_login_passwd"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def send_list(self) -> list:
        section = "EMAIL"
        option = "send_list"
        default = []
        try:
            address = self.get_config().get(section=section, option=option)
            value = []
            for _address_splited in address.split(","):
                if _address_splited:
                    value.append(_address_splited.strip())
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @send_list.setter
    def send_list(self, value) -> NoReturn:
        section = "EMAIL"
        option = "send_list"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def cs_list(self) -> list:
        section = "EMAIL"
        option = "cs_list"
        default = []
        try:
            address = self.get_config().get(section=section, option=option)
            value = []
            for _address_splited in address.split(","):
                if _address_splited:
                    value.append(_address_splited.strip())
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @cs_list.setter
    def cs_list(self, value) -> NoReturn:
        section = "EMAIL"
        option = "cs_list"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def dbtype(self) -> str:
        section = "DATABASE"
        option = "dbtype"
        default = "MySQL"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @dbtype.setter
    def dbtype(self, value) -> NoReturn:
        section = "DATABASE"
        option = "dbtype"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def host(self) -> str:
        section = "DATABASE"
        option = "host"
        default = "localhost"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @host.setter
    def host(self, value) -> NoReturn:
        section = "DATABASE"
        option = "host"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def user_mysql(self) -> str:
        section = "DATABASE"
        option = "user"
        default = "root"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @user_mysql.setter
    def user_mysql(self, value) -> NoReturn:
        section = "DATABASE"
        option = "user"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def passwd_mysql(self) -> str:
        section = "DATABASE"
        option = "passwd"
        default = "root"
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @passwd_mysql.setter
    def passwd_mysql(self, value) -> NoReturn:
        section = "DATABASE"
        option = "passwd"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def port(self) -> int:
        section = "DATABASE"
        option = "port"
        default = 3306
        try:
            value = self.get_config().getint(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @port.setter
    def port(self, value) -> NoReturn:
        section = "DATABASE"
        option = "port"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def charset(self) -> str:
        section = "DATABASE"
        option = "charset"
        default = 'utf8'
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @charset.setter
    def charset(self, value) -> NoReturn:
        section = "DATABASE"
        option = "charset"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def result(self) -> str:
        section = "HTML"
        option = "result"
        default = 'result'
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @result.setter
    def result(self, value) -> NoReturn:
        section = "HTML"
        option = "result"
        self._prop_setter(section=section, option=option, value=value)

    @property
    def html(self) -> str:
        section = "HTML"
        option = "html"
        default = 'html'
        try:
            value = self.get_config().get(section=section, option=option)
        except (NoOptionError, NoSectionError):
            value = default
            logger.warning(
                '...\\项目目录\\Config\\config.ini文件未配置 %s.%s 选项，将采用默认值"%s"' %
                (section, option, value))
        return value

    @html.setter
    def html(self, value) -> NoReturn:
        section = "HTML"
        option = "html"
        self._prop_setter(section=section, option=option, value=value)


Config = GetConfig()
